# arcflown.mod    
# by Yu Liu, 03/2001.   Based on survB.mod
# Arc-flow model for spare capacity allocation 
# considering all single NODE failures

set NODES;
set LINKS within {i1 in NODES, NODES diff {i1}};
set FLOWS := {i1 in NODES, NODES diff {i1}};
param M {FLOWS} integer default 1 >=0; 

param R {NODES,LINKS} integer default 0 >= -1 <= 1;
param D {FLOWS,NODES} integer default 0 >= -1 <= 1;

param A {FLOWS, LINKS} binary default 0;
param w {LINKS} integer default 0;
var B {FLOWS, LINKS} binary default 0;
var C {LINKS, LINKS} integer default 0;
var s {LINKS} integer default 0;

minimize work_cost:  sum {(i1,i2) in LINKS} w[i1,i2];
#s.t. mass_ba {(r1,r2) in FLOWS, n1 in NODES}:
#  sum {(i1,i2) in LINKS} A[r1,r2,i1,i2]*R[n1,i1,i2] 
#      = D[r1,r2,n1];
#s.t. cap_aggr {(i1,i2) in LINKS}:
#  w[i1,i2] = sum{(r1,r2) in FLOWS} A[r1,r2,i1,i2];
#problem find_work:  work_cost,  mass_ba, cap_aggr, A, w;

minimize s_cap: sum {(i1,i2) in LINKS} s[i1,i2];

s.t. mass_ba2 {(r1,r2) in FLOWS, n1 in NODES}:
  sum {(i1,i2) in LINKS} B[r1,r2,i1,i2]*R[n1,i1,i2]=D[r1,r2,n1];

s.t. cap_aggr2 {(i1,i2) in LINKS, (j1, j2) in LINKS}:
  s[i1,i2] >= (C[i1,i2,j1,j2]+C[i1,i2,j2,j1]);

s.t. spare_prov {(i1,i2) in LINKS, (j1,j2) in LINKS}:
  C[i1,i2,j1,j2] = sum{(r1,r2) in FLOWS} 
    M[r1,r2] * (B[r1,r2,i1,i2] * A[r1,r2,j1,j2]);

s.t. link_disjoint {(r1,r2) in FLOWS,(i1,i2) in LINKS}:
  A[r1,r2,i1,i2] + B[r1,r2,i1,i2] <=1;

problem spare_cap:
 s_cap,  mass_ba2, cap_aggr2, 
  spare_prov, link_disjoint, B, C, s;

set TYPE; #:= {1,3,12,48,192};
param unit {TYPE};
var stype {LINKS, TYPE} binary default 0;
var ntype {LINKS, TYPE} integer default 0 >= 0;

minimize s_cost: 
 sum {(i1,i2) in LINKS, k in TYPE} ntype[i1,i2, k] * unit[k];

s.t. one_type {(i1,i2) in LINKS}: 
 sum {k in TYPE} stype[i1,i2,k] <= 1;
s.t. num_one {(i1,i2) in LINKS, k in TYPE diff {192}}: 
 ntype[i1,i2,k] <= 1 ;
s.t. num_more {(i1,i2) in LINKS}: 
 ntype[i1,i2,192] <= stype[i1,i2,192] *20;
s.t. enough {(i1,i2) in LINKS}:
 sum{k in TYPE} ntype[i1,i2,k] * k >= w[i1,i2]+ s[i1,i2];

problem spare_cost:
 s_cost,  mass_ba2, cap_aggr2, 
  spare_prov, link_disjoint, 
  one_type, num_one, num_more, enough,
  B, C, s, stype, ntype;

problem cal_s_cost:
 s_cost,  
  one_type, num_one, num_more, enough,
  stype, ntype;

param MaxNode integer default 5;
param MaxLink integer default 7;
param MaxFlow integer default 10;
param MaxHop integer default 6;

param t1 integer;
param t2 integer;